package com.qdlc.p2p.biz.processor.task;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.core.queue.ITaskProcessor;
import com.qdlc.p2p.common.core.queue.QueueHandlers;
import com.qdlc.p2p.common.core.queue.ReplayValueEvent;
import com.qdlc.p2p.common.core.queue.TaskProcessorException;
import com.qdlc.p2p.common.core.queue.ValueEvent;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.util.MailUtil;

public abstract class AbstractTaskProcessor implements ITaskProcessor {

	private static final Logger logger = Logger.getLogger(AbstractTaskProcessor.class);

	@Override
	public boolean hasTransaction() {
		return false;
	}	
	
	protected void preProcess(){
		logger.info("++++ pre process:" + this.getClass().getSimpleName());
	}

	@SuppressWarnings("unchecked")
	public void internalProcess(ValueEvent event) throws TaskProcessorException{
        Exception currentException = null;
        String result = "success";
        Global.setIP(event.getClientIp());

        try {
            //前置处理方法
            preProcess();
            //真正的处理业务
            process0(event);
            //后置处理方法
            postProcess(event);
        } catch (BusinessException e) {
            //捕获业务异常（不知道干嘛用的，考虑去掉）
            currentException = e;
            e.printStackTrace();
            result = e.getMessage();
        } catch (Exception e) {
            //捕获任务异常
            currentException = e;
            result = "系统繁忙!请稍后重试!";
        } finally {
            // 在需要保存系统处理信息的地方直接保存进来（不知道干嘛用的，考虑去掉）
            // 投标时 返回队列处理结果用
            String resultFlag = event.getResultFlag();
            if (resultFlag != null) {
                Global.TASK_RESULT_MAP.put(resultFlag, result);
            }
            //主动抛出异常，解决事务回滚
            if (currentException != null) {
                throw new TaskProcessorException(event, currentException);
            }
        }
    }
	
	@Override
	public void process(ValueEvent event) throws TaskProcessorException {
		internalProcess(event);
	}

	@Override
	public void transactionProcesss(ValueEvent event) throws TaskProcessorException {
		internalProcess(event);
	}

	protected abstract void process0(ValueEvent event) throws TaskProcessorException;

	protected void postProcess(ValueEvent event){
		logger.info("++++ post process:" + this.getClass().getSimpleName());
	}
	
	/**
	 * 处理异常
	 * @param hander
	 * @param event
	 * @param exception
	 */
	@Override
	public void exceptionProcess(ValueEvent event, Exception exception){
		logger.info("++++ process exception:" + exception.getMessage(), exception);
		replayProcess(event);
	}
	
	/**
	 * 重新入队列处理
	 * @param event
	 */
	protected void replayProcess(ValueEvent event){
		if(event instanceof ReplayValueEvent){
			ReplayValueEvent replayEvent = (ReplayValueEvent)event;
			if(replayEvent.isFinalFailure()){
				String eventJson = JSONObject.toJSONString(replayEvent);
				MailUtil.sendMail(eventJson);
			}else{
				replayEvent.incrementAndGet();
				replayEvent.setLastestFailureTime(System.currentTimeMillis());
				QueueHandlers.put(replayEvent);
			}
		}		
	}
}
